package cn.catsdad.util;

import cn.catsdad.constant.iConstant.ICommonWarningType;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 反射util
 *
 * @author xuyl
 * @version 1.0 2024/8/3
 */
@Slf4j
@SuppressWarnings({ICommonWarningType.ALL})
public class ReflectUtil {

    /**
     * 获取类上的注解值
     *
     * @param targetClass     类class
     * @param annotationClass 注解class
     * @param keyName         注解中的属性
     * @return 注解值
     */
    public static Object getAnnotationValue(Class targetClass, Class annotationClass, String keyName) {
        Map<String, Object> stringObjectMap = multiGetAnnotationValue(targetClass, annotationClass, keyName);
        return stringObjectMap.get(keyName);
    }

    /**
     * 批量获取类上的注解值
     *
     * @param targetClass     类class
     * @param annotationClass 注解class
     * @param keyNames        注解中的属性
     * @return 注解值
     */
    public static Map<String, Object> multiGetAnnotationValue(Class targetClass, Class annotationClass, String... keyNames) {
        Map<String, Object> result = new HashMap<>();
        if (targetClass != null && annotationClass != null && StringUtil.isNotEmpty(keyNames)) {
            Annotation targetAnno = targetClass.getAnnotation(annotationClass);
            if (targetAnno != null) {
                Class<? extends Annotation> annotationType = targetAnno.annotationType();
                Method[] methods = annotationType.getMethods();
                List<String> keyNameList = Arrays.asList(keyNames);
                if (StringUtil.isNotEmpty(methods)) {
                    for (Method method : methods) {
                        if (keyNameList.contains(method.getName())) {
                            try {
                                Object annoValue = method.invoke(targetAnno, null);
                                result.put(method.getName(), annoValue);
                            } catch (Exception e) {
                                log.error("获取注解值失败，注解为：{}，属性为：{}", targetAnno, method);
                                log.error(e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

}
